package com.example.config.shiro;

import com.example.util.CredentialsUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.lang.codec.CodecSupport;
import org.apache.shiro.lang.util.ByteSource;

import java.util.Objects;

/**
 * 加盐加密 密码校验器
 */
public class AddSaltCredentialsMatcher extends CodecSupport
        implements CredentialsMatcher {

    /**
     *
     * @param authenticationToken 前端提供的UsernamePasswordToken，里面包含前端提供的账号密码
     * @param authenticationInfo CustomRealm登录认证方法的返回值，服务端存在的账号密码（SQL语句查出来的）
     * @return
     */
    @Override
    public boolean doCredentialsMatch(AuthenticationToken authenticationToken,
                                      AuthenticationInfo authenticationInfo) {
        // 把登录请求中，前端传过来的密码再使用注册时的规则，加密一次
        Object tokenCredentials = authenticationToken.getCredentials();
        // 用户输入的密码
        String password = new String(toBytes(tokenCredentials));
        // 获取服务端的密码
        Object inFoCredentials = authenticationInfo.getCredentials();
        SimpleAuthenticationInfo info =
                (SimpleAuthenticationInfo) authenticationInfo;
        // 字节数据的salt
        ByteSource credentialsSalt = info.getCredentialsSalt();
        // 数据库的salt
        String salt = new String(toBytes(credentialsSalt));
        // 用户输入的密码和数据库中的salt进行加密
        String md5Pwd = CredentialsUtils.cryptPassword(password, salt);
        // 加密过后的密码跟数据库中的密码比较
        return Objects.equals(inFoCredentials, md5Pwd);
    }
}
